package com.cnfangmao.masterdata.common.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableId;

/**
 * @description: 含有会话信息的Model解析类
 * @author: chenxc
 * @date: 2020年4月18日 下午3:51:54
 */
public class ModelUtils {

	/**
	 * 
	 * @param model
	 * @param dto
	 * @return
	 */
	public static String parseObject(Object model, Object dto) {
		BeanUtils.copyProperties(model, dto);
		return JSONObject.toJSONString(dto);
	}

	/**
	 * Parse DTO object to Model object
	 * 
	 * @param <T>
	 * @param dto
	 * @param modelClazz
	 * @param operation
	 * @return
	 * @throws Exception
	 */
	public static <T> T parseObject(Object dto, Class<T> modelClazz, String operation) throws Exception {
		String dtoJson = JSONObject.toJSONString(dto);

		T model = JSONObject.parseObject(dtoJson, modelClazz);

		Field[] fields = model.getClass().getDeclaredFields();
		String idName = null;
		for (Field field : fields) {
			TableId tableIdAnn = field.getAnnotation(TableId.class);
			if (tableIdAnn != null) {
				idName = field.getName();
			}
		}

		final String idNameFinal = idName;
		BeanInfo beanInfo = Introspector.getBeanInfo(model.getClass());
		List<PropertyDescriptor> descriptors = Arrays.stream(beanInfo.getPropertyDescriptors()).filter(p -> {
			String name = p.getName();
			boolean retFlag = false;
			if ("create".equals(operation)) {
				retFlag = "createdOn".equals(name) || "createdBy".equals(name) || "modifiedOn".equals(name)
						|| "modifiedBy".equals(name) || name.equals(idNameFinal);
			} else if ("update".equals(operation)) {
				retFlag = "modifiedOn".equals(name) || "modifiedBy".equals(name);
			}
			return retFlag;
		}).collect(Collectors.toList());

		for (PropertyDescriptor descriptor : descriptors) {
			String fieldName = descriptor.getName();
			// 获取set方法
			Method writeMethod = descriptor.getWriteMethod();
			if (fieldName.equals(idName)) {
				writeMethod.invoke(model, SnowFlakeUtils.generator());
			}
			switch (fieldName) {
			case "createdOn":
				writeMethod.invoke(model, new Date());
				break;
			case "createdBy":
				// writeMethod.invoke(model, SecurityUtils.getSubject());
				break;
			case "modifiedOn":
				writeMethod.invoke(model, new Date());
				break;
			case "modifiedBy":
				// writeMethod.invoke(model, SecurityUtils.getSubject());
				break;
			default:
				break;
			}
		}

		return model;
	}
	
	/**
	 * @description: 将一个对象转成map 
	 * @author: chenxc
	 * @date: 2020年4月23日 下午12:58:25
	 * @param: @param obj
	 * @param: @return
	 * @param: @throws IllegalAccessException      
	 * @return: Map<String,Object>      
	 * @throws
	 */
	public static Map<String, Object> objectToMap(Object obj) {
		Map<String, Object> map = new HashMap<String, Object>();
		
		Class<?> clazz = obj.getClass();
		
		for (Field field : clazz.getDeclaredFields()) {
			field.setAccessible(true);
			String fieldName = field.getName();
			Object value = null;
			try {
				value = field.get(obj);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			map.put(fieldName, value);
		}
		
		return map;
	}
}
